from typing import List, Tuple
from ConfigManager import ConfigManager

class TextChunker:
    """
    A text chunking utility for RAG (Retrieval-Augmented Generation) applications.
    Splits long texts into chunks with specified size and overlap (padding).
    """
    
    def __init__(self):
        """
        Initialize the TextChunker with specified chunk size and padding.
        
        Args:
            chunk_size: Maximum length of each text chunk in characters. Default is 4000.
            padding: Overlap between consecutive chunks in characters. Default is 500.
        """
        self.chunk_size = int(ConfigManager().get("embedding_context_size"))
        self.padding = int(ConfigManager().get("embedding_context_padding"))
        if self.chunk_size <= 0:
            raise ValueError("chunk_size must be positive")
        if self.padding < 0:
            raise ValueError("padding must be non-negative")
        if self.padding >= self.chunk_size:
            raise ValueError("padding must be smaller than chunk_size")
            
    
    def chunk_text(self, text: str) -> list[str]:
        """
        Split the input text into chunks with specified size and padding.
        
        Args:
            text: The input text to be chunked.
            
        Returns:
            A list of text chunks.
        """
        if not text:
            return []
            
        chunks = []
        start = 0
        text_length = len(text)
        
        while start < text_length:
            end = min(start + self.chunk_size, text_length)
            chunk = text[start:end]
            chunks.append(chunk)
            
            # Break if we've reached the end of the text
            if end >= text_length:
                break   
            # Move the start position forward, accounting for padding
            start = end - self.padding
        return chunks
    
    @staticmethod
    def _find_nearest_split_point(text: str, position: int, look_back: int = 100, look_forward: int = 100) -> int:
        """
        Helper method to find a natural split point near the given position.
        Looks for the nearest sentence boundary or whitespace.
        
        Args:
            text: The text to search in.
            position: The ideal split position.
            look_back: How many characters to look back from position.
            look_forward: How many characters to look forward from position.
            
        Returns:
            The nearest natural split position.
        """
        # Define potential split characters
        split_chars = {'.', '!', '?', '\n', '\r', ';', '。', '！', '？'}
        
        # Search forward first
        for i in range(position, min(position + look_forward + 1, len(text))):
            if text[i] in split_chars:
                return i + 1  # Include the split character in the previous chunk
                
        # Then search backward
        for i in range(position, max(position - look_back - 1, 0) - 1, -1):
            if text[i] in split_chars:
                return i + 1
                
        # If no natural split found, return the original position
        return position